package com.ekgc.addressbook.service.impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ekgc.addressbook.base.util.PinyinUtils;
import com.ekgc.addressbook.common.ContactGroupRelation;
import com.ekgc.addressbook.common.Contacts;
import com.ekgc.addressbook.dao.mapper.ContactMapper;

import com.ekgc.addressbook.dao.mapper.GroupMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ContactServiceImpl extends ServiceImpl<ContactMapper, Contacts> implements ContactService {

    @Autowired
    private ContactMapper contactMapper;

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private GroupService groupService;

    @Autowired
    private PinyinUtils pinyinUtils; // 新增：注入拼音工具类

    // 重写 ContactService 接口中的 queryContacts 方法
    @Override
    public IPage<Contacts> queryContacts(int pageNo, int pageSize, String keyword, String phoneNumber, int groupid) {
        try {
            // 参数校验
            if (pageNo <= 0 || pageSize <= 0) {
                throw new IllegalArgumentException("页码和每页记录数必须为正整数");
            }

            // 1. 执行原查询逻辑
            Page<Contacts> page = new Page<>(pageNo, pageSize);
            IPage<Contacts> result = contactMapper.selectContactsWithGroup(page, keyword, phoneNumber, groupid);

            // 2. 判断是否有结果
            if (result.getTotal() > 0 || keyword == null || keyword.isEmpty()) {
                return result; // 有结果或无关键词直接返回
            }

            // 3. 无结果时执行拼音搜索（纯Java实现）
            log.info("原查询无结果，开始执行拼音搜索，keyword={}", keyword);

            // 3.1 查询所有可能的联系人（不带关键词过滤，只过滤group和phoneNumber）
            IPage<Contacts> allPossibleContacts = contactMapper.selectAllContacts(
                    new Page<>(1, Integer.MAX_VALUE), // 查询全量数据
                    phoneNumber,
                    groupid
            );

            // 3.2 在Java内存中进行拼音过滤
            List<Contacts> filteredContacts = allPossibleContacts.getRecords().stream()
                    .filter(contact -> {
                        String name = contact.getName();
                        String pinyin = pinyinUtils.getFullPinyin(name); // 转全拼，如"zhangying"
                        String initials = pinyinUtils.getInitials(name); // 转声母，如"ZY"

                        // 匹配全拼（小写）或声母（大写）
                        return pinyin.contains(keyword.toLowerCase()) ||
                                initials.contains(keyword.toUpperCase());
                    })
                    .collect(Collectors.toList());

            // 3.3 重新分页处理
            int totalCount = filteredContacts.size();
            int startIndex = (pageNo - 1) * pageSize;
            int endIndex = Math.min(startIndex + pageSize, totalCount);

            List<Contacts> pageData = filteredContacts.subList(
                    Math.min(startIndex, totalCount), // 防止越界
                    endIndex
            );

            // 3.4 构建新的分页结果
            Page<Contacts> pinyinPage = new Page<>(pageNo, pageSize, totalCount);
            pinyinPage.setRecords(pageData);

            return pinyinPage;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 修改拼音搜索方法，设置默认数据库函数
    private IPage<Contacts> performPinyinSearch(int pageNo, int pageSize, String keyword, String phoneNumber, int groupid) {
        // 获取拼音和声母
        String pinyinKeyword = pinyinUtils.getFullPinyin(keyword);
        String initialsKeyword = pinyinUtils.getInitials(keyword).toUpperCase();

        // 创建新的Page对象
        Page<Contacts> page = new Page<>(pageNo, pageSize);

        // 设置数据库拼音函数（根据你的数据库类型调整）
        String pinyinFunction = "CONVERT(c.name USING gbk)"; // MySQL
        String initialsFunction = "SUBSTRING(CONVERT(c.name USING gbk),1,1)"; // MySQL

        // 执行拼音搜索（调用新的Mapper方法）
        return contactMapper.selectContactsWithPinyin(
                page,
                pinyinKeyword,
                initialsKeyword,
                phoneNumber,
                groupid,
                pinyinFunction,
                initialsFunction
        );
    }

    @Override
    public boolean addContact(Contacts contacts ,int UserId) {
        log.info("增加操作：contacts:{},userid:{}",contacts,UserId);
        if (!contactMapper.isexists(contacts.getPhoneNumber(), UserId)) {
            int result = contactMapper.insert(contacts);
            return result > 0;
        }
        else{
            return false;
        }
    }

    @Transactional
    @Override
    public boolean deleteContact(String phoneNumber,int userId) {
        // 查询联系人 ID
        Integer contactId = contactMapper.findContactIdByPhoneNumberAndUserId(phoneNumber, userId);
        if (contactId != null) {
            // 删除联系人 - 分组关联记录
            int relationDeleteCount = contactMapper.deleteContactGroupRelationByContactId(contactId);
            // 删除联系人记录
            int contactDeleteCount = contactMapper.deleteContactByContactId(contactId);
            return relationDeleteCount >= 0 && contactDeleteCount > 0;
        }
        return false;

    }

    @Override
    public boolean updateContact(Contacts contacts) {
        int result = contactMapper.updateById(contacts);
        return result > 0;
    }

    /**
     * 根据 contactId 更新或插入联系人 - 分组关联记录
     * @param contactId 联系人 ID
     * @param newGroupId 新的分组 ID
     */
    @Override
    public void updateContactGroup(Integer contactId, Integer newGroupId) {
        contactMapper.updateContactGroup(contactId, newGroupId);
        ContactGroupRelation relation = groupMapper.selectByContactId(contactId);
        if (relation != null) {
            // 记录存在，更新分组 ID
            groupMapper.updateContactGroupRelation(contactId, newGroupId);
        } else {
            // 记录不存在，插入新记录
            groupMapper.insertContactGroupRelation(contactId, newGroupId);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int importContacts(Integer userId, MultipartFile file) throws IOException {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8))) {
            int successCount = 0;
            boolean isHeader = true; // 标记标题行

            String line;
            while ((line = reader.readLine()) != null) {
                // 跳过标题行
                if (isHeader) {
                    isHeader = false;
                    continue;
                }

                try {
                    // 使用更健壮的CSV分割方法
                    String[] data = parseCsvLine(line);

                    if (data.length >= 7) {
                        Contacts contact = mapToContact(userId, data);
                        if (contact != null) { // 新增：避免空指针
                            contactMapper.insert(contact);
                            successCount++;
                        }
                    } else {
                        log.warn("CSV行数据不完整: {}", line);
                    }
                } catch (Exception e) {
                    // 记录更详细的错误信息
                    log.error("解析CSV行失败: {}", line, e);
                }
            }

            return successCount;
        }
    }

    // 处理带引号的CSV行
    private String[] parseCsvLine(String line) {
        // 使用正则表达式处理带引号的字段
        return line.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
    }

    private Contacts mapToContact(Integer userId, String[] data) {
        // 新增：校验CSV列数是否足够
        if (data.length < 7) {
            log.warn("CSV行数据缺失字段: {}", Arrays.toString(data));
            return null;
        }

        Contacts contact = new Contacts();
        contact.setUserId(userId);

        contact.setName(removeQuotes(data[0]));
        contact.setPhoneNumber(removeQuotes(data[1]));
        contact.setGender(parseGender(removeQuotes(data[2])));
        contact.setBirthDate(parseLocalDate(removeQuotes(data[3])));
        contact.setEmail(removeQuotes(data[4]));
        contact.setAddress(removeQuotes(data[5]));
        contact.setUsergroups(removeQuotes(data[6]));

        // 处理分组逻辑
        if (data.length > 7 && StringUtils.isNotBlank(data[7])) {
            Integer groupId = groupService.getOrCreateGroup(userId, removeQuotes(data[7]));
            contact.setGroupid(groupId);
        }

        return contact;
    }

    // 处理性别转换
    private Integer parseGender(String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        // 处理中文性别
        if ("男".equalsIgnoreCase(value)) {
            return 0;
        }
        if ("女".equalsIgnoreCase(value)) {
            return 1;
        }

        // 尝试作为数字解析
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            log.error("无法解析性别字段: {}", value);
            return null;
        }
    }

    // 安全转换Integer
    private Integer parseInteger(String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            log.error("无法将字符串转换为Integer: {}", value);
            return null;
        }
    }

    // 修改：增强日期解析逻辑，支持多种格式
    private static final List<DateTimeFormatter> DATE_FORMATTERS = Arrays.asList(
            DateTimeFormatter.ofPattern("yyyy-MM-dd"),
            DateTimeFormatter.ofPattern("yyyy/MM/dd"),
            DateTimeFormatter.ofPattern("MM/dd/yyyy"),
            DateTimeFormatter.ofPattern("yyyyMMdd")
    );

    private LocalDate parseLocalDate(String value) {
        if (value == null || value.isEmpty()) {
            return null;
        }

        // 去除所有空白字符（包括制表符、换行符等）
        value = value.replaceAll("\\s+", "");

        try {
            // 尝试多种格式解析
            for (DateTimeFormatter formatter : DATE_FORMATTERS) {
                try {
                    return LocalDate.parse(value, formatter);
                } catch (DateTimeException e) {
                    // 继续尝试下一种格式
                }
            }

            // 所有格式均失败时记录日志
            log.error("不支持的日期格式: {}", value);
            return null;
        } catch (Exception e) {
            log.error("解析日期失败: {}", value, e);
            return null;
        }
    }

    // 修改：增强空白字符处理
    private String removeQuotes(String value) {
        if (value == null) return null;
        // 去除首尾引号、空格、制表符、换行符等所有空白字符
        value = value.trim().replaceAll("^\"|\"$", "");
        return value.isEmpty() ? null : value;
    }
}
